#pragma once

#include "../umlmodel_global.h"

#include <memory>
#include <vector>

#include "Behavior.h"

using std::make_shared;
using std::shared_ptr;
using std::vector;

namespace uml {
class ActivityEdge;
class ActivityGroup;
class ActivityNode;
class ActivityPartition;
class StructuredActivityNode;
class Variable;

/// <summary>
/// Activity
/// An Activity is the specification of parameterized Behavior as the coordinated
/// sequencing of subordinate units.
/// </summary>
class UMLMODEL_EXPORT Activity : public Behavior {

public: // Constructors and destructors
    explicit Activity(const QString& umlType="uml::Activity");

public: // JsonSerializable override
    void fromJson(const QJsonObject& json, QStringList& errorList) override;
    void toJson(QJsonObject& json) override;

public: // Properties
    /// <summary>
    /// edges getter
    /// ActivityEdges expressing flow between the nodes of the Activity.
    /// </summary>
    vector<shared_ptr<ActivityEdge>>& edges();

    /// <summary>
    /// groups getter
    /// Top-level ActivityGroups in the Activity.
    /// </summary>
    vector<shared_ptr<ActivityGroup>>& groups();

    /// <summary>
    /// isReadOnly getter
    /// If true, this Activity must not make any changes to objects. The default is
    /// false (an Activity may make nonlocal changes). (This is an assertion, not an
    /// executable property. It may be used by an execution engine to optimize model
    /// execution. If the assertion is violated by the Activity, then the model is
    /// ill-formed.) 
    /// </summary>
    bool isReadOnly() const;

    /// <summary>
    /// isReadOnly setter
    /// If true, this Activity must not make any changes to objects. The default is
    /// false (an Activity may make nonlocal changes). (This is an assertion, not an
    /// executable property. It may be used by an execution engine to optimize model
    /// execution. If the assertion is violated by the Activity, then the model is
    /// ill-formed.) 
    /// </summary>
    void setIsReadOnly(bool value);

    /// <summary>
    /// isSingleExecution getter
    /// If true, all invocations of the Activity are handled by the same execution.
    /// </summary>
    bool isSingleExecution() const;

    /// <summary>
    /// isSingleExecution setter
    /// If true, all invocations of the Activity are handled by the same execution.
    /// </summary>
    void setIsSingleExecution(bool value);

    /// <summary>
    /// nodes getter
    /// ActivityNodes coordinated by the Activity.
    /// </summary>
    vector<shared_ptr<ActivityNode>>& nodes();

    /// <summary>
    /// partitions getter
    /// Top-level ActivityPartitions in the Activity.
    /// </summary>
    vector<shared_ptr<ActivityPartition>>& partitions();

    /// <summary>
    /// structuredNodes getter
    /// Top-level StructuredActivityNodes in the Activity.
    /// </summary>
    vector<shared_ptr<StructuredActivityNode>>& structuredNodes();

    /// <summary>
    /// variables getter
    /// Top-level Variables defined by the Activity.
    /// </summary>
    vector<shared_ptr<Variable>>& variables();

private: // Fields
    /// <summary>
    /// edges
    /// ActivityEdges expressing flow between the nodes of the Activity.
    /// </summary>
    vector<shared_ptr<ActivityEdge>> edges_;

    /// <summary>
    /// groups
    /// Top-level ActivityGroups in the Activity.
    /// </summary>
    vector<shared_ptr<ActivityGroup>> groups_;

    /// <summary>
    /// isReadOnly
    /// If true, this Activity must not make any changes to objects. The default is
    /// false (an Activity may make nonlocal changes). (This is an assertion, not an
    /// executable property. It may be used by an execution engine to optimize model
    /// execution. If the assertion is violated by the Activity, then the model is
    /// ill-formed.) 
    /// </summary>
    const static bool isReadOnly_default_;
    bool isReadOnly_= isReadOnly_default_;

    /// <summary>
    /// isSingleExecution
    /// If true, all invocations of the Activity are handled by the same execution.
    /// </summary>
    const static bool isSingleExecution_default_;
    bool isSingleExecution_= isSingleExecution_default_;

    /// <summary>
    /// nodes
    /// ActivityNodes coordinated by the Activity.
    /// </summary>
    vector<shared_ptr<ActivityNode>> nodes_;

    /// <summary>
    /// partitions
    /// Top-level ActivityPartitions in the Activity.
    /// </summary>
    vector<shared_ptr<ActivityPartition>> partitions_;

    /// <summary>
    /// structuredNodes
    /// Top-level StructuredActivityNodes in the Activity.
    /// </summary>
    vector<shared_ptr<StructuredActivityNode>> structuredNodes_;

    /// <summary>
    /// variables
    /// Top-level Variables defined by the Activity.
    /// </summary>
    vector<shared_ptr<Variable>> variables_;

};

} // namespace uml
